<template>
  <a-modal
    :width="1152"
    title="可视化图表"
    :visible="visible"
    ok-text="确定"
    cancel-text="取消"
    @ok="handleOk"
    @cancel="handleCancel"
  >
    <div class="modal-body">
      <div class="section-chart">
        <chart
          v-if="renderFlag && chartType && chartType !== 'table'"
          :chart-type="chartType"
          :config="getRenderOption"
          @chartinit="onChartInit"
        />
        <div v-else class="default-chart-box">
          <img
            alt="chart demo"
            :src="`${publicPath}${chartImgSrc(chartType)}`"
          />
          <span>当前无配置</span>
          <span>右侧完成数据配置</span>
        </div>
      </div>
      <form-render
        from="modal"
        :chart-type="chartType"
        :widget-type="widgetType"
        :form-data="getRenderOption"
        :widget-info="widgetInfo"
        :panel-list="formRenderConfig"
        :project-id="projectId"
        :dataset-list="datasetList"
        :chart-type-change-flag="true"
        class="form-render"
        @change="onFormSettingChange"
        @chartTypeChange="onChartTypeChange"
      />
    </div>
  </a-modal>
</template>

<script lang="ts">
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
import FormRender from '@/components/common/VisualizationDashboard/FormRender.vue'
import Chart from '@/components/chart/chart.vue'
import ChartProtoConfig from '@/components/common/VisualizationComp/proto-config'
import { getDetailDefaultOptionsByChartType } from '@/components/common/VisualizationComp/default-chart-options'
import {
  parseSettingToChartOption,
  parseChartType,
  parseChartProtoConfig,
  parseChartOptionToFunction,
} from '@/components/common/VisualizationDashboard/util'
import { cloneDeep } from 'lodash'
import { KeyValueStore } from '@/components/vueGridLayout/interfate/grid-Item-data-inteface'
import { bindChartData } from '@/util/common'
import { IDatasetList } from '@/components/common/VisualizationDashboard/interface'
import { chart2ArrayChartType, chartMaps } from '@/config/contant'
import { publicPath } from '@/api/constants'

interface KeyValue {
  [key: string]: any
}

@Component({
  components: {
    FormRender,
    Chart,
  },
})
export default class ModalVisualization extends Vue {
  @Prop({ default: () => ({}) }) chartConfig!: KeyValue
  @Prop({ default: () => [] }) datasetList!: IDatasetList // 数据集列表
  @Prop({ default: false }) visible!: boolean

  private renderFlag: boolean = false // 是否可以渲染chart
  private renderOption: KeyValue = {} // 渲染的chart 配置
  private chartType: string = 'pieChart'

  private chartInstance: any = undefined
  private widgetInfo: any = {} // widgetInfo
  private chartMaps = chartMaps

  private modalModeOptions: KeyValue = {
    // 适合在modal模式下显示的图表配置，如：尺寸更大，标题字号更大等
    size: [810, 450],
    xAxisFontSize: 12,
    padding: [10, 20, 10, 10],
    xAxisTitleFontSize: 14,
    yAxisTitleFontSize: 14,
    xAxisIsShow: true,
    yAxisIsShow: true,
  }

  private publicPath = publicPath // 基础URL

  private get chartTypeList() {
    return Object.keys(chartMaps)
      .filter(
        (key) =>
          ![
            'text',
            'table',
            'configuration',
            'parallelCoordinates',
            'geographicMap',
            'filterForm',
            'graph',
          ].includes(key)
      )
      .reduce((pre, key) => {
        // @ts-ignore
        pre.push(...chartMaps[key])
        return pre
      }, [])
  }

  private chartImgSrc(type: string = 'pieChart') {
    const test: any = this.chartTypeList
    // eslint-disable-next-line no-restricted-syntax
    for (const item of test) {
      if (item.name === type) {
        return item.imgSrc
      }
    }
    return '/icon/components/pieChart.png'
  }

  private get projectId() {
    return this.$route.params.id
  }

  private get widgetType() {
    return this.chartConfig.widgetType || 'pipeline'
  }

  // 配置表单proto config
  private get formRenderConfig() {
    return parseChartProtoConfig(
      this.chartType,
      ChartProtoConfig[this.chartType],
      this.renderOption
    )
  }

  /**
   * 默认的渲染配置
   */
  private get defaultRenderOptions() {
    return getDetailDefaultOptionsByChartType(this.chartType)
  }

  /**
   * 集合多方成最终的渲染配置
   */
  private get getRenderOption() {
    return {
      ...this.defaultRenderOptions,
      ...this.renderOption,
      ...this.modalModeOptions,
    }
  }

  // chartConfig变化
  @Watch('chartConfig', { deep: true })
  onChartConfigChange() {
    // this.renderFlag = false
    // console.log('chartConfig',this.chartConfig)
    if (Object.keys(this.chartConfig).length > 0) {
      this.chartType = this.chartConfig.chartType
        ? parseChartType(this.chartConfig.chartType)
        : 'pieChart'

      this.renderOption = this.chartConfig.chartOptions
        ? cloneDeep(this.chartConfig.chartOptions)
        : {}
      parseChartOptionToFunction(this.renderOption) // 转换formatter 函数
      this.widgetInfo = {
        id: this.chartConfig.chartOptions?.dataId,
        type: this.chartConfig.chartOptions?.dataType,
        widgetJson: this.chartConfig.widgetJson,
      }
    }
    this.renderFlag = (this.chartConfig.chartOptions?.value?.length || 0) > 0
  }

  // chartType变化
  private onChartTypeChange(chartType: string) {
    // 仅更改chartType时在FetchForm.vue中被拦截 所有现在默认更改chartType清空所有配置
    this.renderFlag = false
    this.chartType = chartType
    this.renderOption = {
      dataId: this.renderOption.dataId,
      dataType: this.renderOption.dataType,
    }
    this.widgetInfo = {
      ...this.widgetInfo,
      widgetJson: undefined,
    }
  }

  /**
   * 处理geomap的form数据
   */
  private parseGeoMapFormSetting(data: KeyValue) {
    this.renderOption.glyphConfig = {
      ...this.renderOption.glyphConfig,
      ...data,
    }

    // 记住地图中心，需要调用api获取
    if (data.rememberMapCenter) {
      this.renderOption.mapCenter = this.chartInstance?.getMapCenter()
    } else {
      delete this.renderOption.mapCenter
    }
  }

  private onFormSettingChange(formSetting: KeyValueStore) {
    this.renderFlag = true
    if (this.chartType === 'table') {
      this.onChangeTableConfig(formSetting)
      return
    }
    const { type, data, widgetInfo } = formSetting
    if (type === 'property') {
      if (this.chartType === 'geographicMap') {
        this.parseGeoMapFormSetting(data)
      } else {
        this.renderOption = parseSettingToChartOption({
          ...this.renderOption,
          ...data,
        })
      }
    } else if (type === 'fetch') {
      // 获取数据配置变化
      const { widgetJson, id, type: dataType } = widgetInfo
      const { keys, values } = widgetJson.config
      const renderOption: any = {
        ...this.renderOption,
        value: data,
        labelKey: keys[0].col,
        valueKey: values[0].col,
        dataId: id,
        dataType,
      }
      // 构造假的gridItem和dataResult 过一遍bindChartData
      const gridItem = {
        chartType: [this.chartType, this.chartType],
        chartOptions: renderOption,
        x: '',
        y: '',
        w: '',
        h: '',
        i: '',
      }
      const dataResult = {
        query: {
          data: {
            id,
            type: dataType,
            widgetJson,
          },
        },
        data,
        columns: [],
        formData: cloneDeep(renderOption),
      }
      const parsedGridItem = bindChartData(gridItem, dataResult)
      // console.log(parsedGridItem)
      this.renderOption = cloneDeep({
        ...renderOption,
        ...parsedGridItem?.chartOptions,
      })
      parseChartOptionToFunction(this.renderOption)
      this.widgetInfo = widgetInfo // 更新本地的widgetInfo
    }
    this.parseDiffBarConfig()
  }

  /**
   * 差异BarChart是单独的一种类型
   */
  private parseDiffBarConfig() {
    if (this.chartType !== 'barChart') {
      return
    }
    const { diffBar } = this.renderOption
    if (diffBar === true) {
      this.renderOption.realChartType = 'diffBarChart'
    } else if (diffBar === false) {
      this.renderOption.realChartType = 'barChart'
    }
  }

  onChangeTableConfig(formSetting: any) {
    const { data, widgetInfo, extraFormData = {} } = formSetting
    const { id, type: dataType } = widgetInfo
    this.renderOption = {
      ...this.renderOption,
      dataId: id,
      dataType,
      ...extraFormData,
    }
    if (data) {
      this.renderOption.value = data
    }
  }

  private handleOk() {
    if (this.chartType === undefined || this.chartType === '') {
      this.$message.error('请选择可视化类型')
      return
    }
    if (this.widgetInfo.widgetJson === undefined) {
      this.$message.error('请完善数据表单')
      return
    }
    const widget = {
      data: {
        chartType: chart2ArrayChartType[this.chartType],
        chartOptions: {
          ...this.defaultRenderOptions,
          ...this.renderOption,
        },
        widgetJson: this.widgetInfo.widgetJson,
      },
      name: this.chartType,
      tid: this.widgetInfo.id,
      type: this.widgetInfo.type,
    }
    this.chartType = ''
    this.$emit('ok', widget)
    this.renderOption = {}
  }

  private handleCancel() {
    this.$emit('cancel')
    this.renderFlag = false
    this.renderOption = {}
    this.widgetInfo = {}
  }

  /**
   * chart 初始化后获取chart示例
   */
  private onChartInit(instance: Vue | Element | undefined) {
    this.chartInstance = instance
  }
}
</script>

<style lang="less" scoped>
/deep/ .ant-modal-body {
  padding: 0;
}

.default-chart-box {
  align-items: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  margin-top: 100px;
}

.modal-body {
  background-color: #f6f6f6;
  display: flex;
  // height: calc(100% - 108px);

  .section-chart {
    background-color: #fff;
    flex: 1;
    height: 462px;
    margin: 24px;
    padding-top: 15px;
  }

  .form-render {
    background-color: #fff;
    height: 510px;
    overflow-y: auto;
    width: 300px;
  }

  /deep/ .ant-form-item-label > label {
    color: #5d637e;
  }
}

/deep/ .chart-title {
  color: #5d637e;
  font-size: 14px;
  font-weight: 500;
  height: 38px;
  line-height: 38px;
}
</style>
